/*
 * @Author: 吴世扬 18368095041@163.com
 * @Date: 2025-02-18 10:00:31
 * @LastEditors: 吴世扬 18368095041@163.com
 * @LastEditTime: 2025-02-18 18:03:45
 * @FilePath: /vue3-admin-server/src/common/utils/tree.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

export type TreeData<T> = {
    children?: T[];
};
export type TreeDataWithParent<T extends TreeData<T>> = T & { parent?: T };
export const treeToArray = <T extends TreeData<T>>(
    tree: T[],
    parent?: TreeDataWithParent<T>
): TreeDataWithParent<T>[] => {
    let res: TreeDataWithParent<T>[] = [];
    for (const item of tree) {
        const { children, ...rest } = item;
        const newItem = { children, ...rest, parent } as TreeDataWithParent<T>;
        res.push(newItem);
        if (children && children.length > 0) {
            res = [...res, ...treeToArray(children, newItem)];
        }
    }
    return res;
};

export function arrayToTree<T extends TreeData<T>>(
    items: TreeDataWithParent<T>[]
): TreeData<T>[] {
    // 用于构建树的辅助函数
    function buildTree(parent?: T): T[] {
        return items
            .filter((item) => item.parent === parent) // 查找所有子节点
            .map((item) => {
                const children = buildTree(item);
                return {
                    ...item,
                    children: children.length > 0 ? children : undefined, // 递归地构建子树
                    parent: undefined // 在树中不需要父节点引用
                };
            });
        // .filter((item) => item.children.length > 0); // 过滤掉没有子节点且不是根节点的元素（可选）
    }

    // 从没有父节点的元素开始构建树
    return buildTree();
}

/**
 * 列表转树
 * @param items 树表
 * @param field 表的主键
 * @param parentField 标识父节点的字段
 * @param sort 排序方法
 */
export const arrayToTreeByField = <T extends object>(
    items: T[],
    field: keyof T,
    parentField: keyof T,
    sort?: (a: T, b: T) => number
): T[] => {
    const hashTable: { [key: string]: T & { children?: T[] } } = {};
    const result: T[] = [];

    // 将每个节点添加到哈希表中
    items.forEach((item) => {
        hashTable[item[field] as unknown as string] = {
            ...item,
            children: []
        };
    });

    // 构建树结构
    items.forEach((item) => {
        const current = hashTable[item[field] as unknown as string];
        const parent = hashTable[item[parentField] as unknown as string];
        if (parent) {
            parent.children?.push(current);
        } else {
            result.push(current);
        }
    });

    // 对每个节点的子节点进行排序
    const sortNodes = (nodes: (T & { children?: T[] })[]) => {
        if (sort) {
            nodes.sort(sort);
        }
        nodes.forEach((node) => {
            if (node.children && node.children.length > 0) {
                sortNodes(node.children);
            }
        });
    };

    sortNodes(result);

    return result;
};
